package apps

import (
	"context"
	"fmt"
	"gitee.com/captials-team/ubdframe/src/common/consts"
	"gitee.com/captials-team/ubdframe/src/common/utils"
	"gitee.com/captials-team/ubdframe/src/domain/configstc"
	"gitee.com/captials-team/ubdframe/src/domain/interfaces"
	"gitee.com/captials-team/ubdframe/src/pkg/gin_http"
	"gitee.com/captials-team/ubdframe/src/pkg/logs"
	"github.com/gin-contrib/cors"
	"github.com/gin-gonic/gin"
	"net/http"
)

type ApiServer struct {
	name         string
	engine       *gin.Engine
	serverConfig configstc.ServerConfig
	module       bool //是否作为模块服务
	server       *http.Server
}

func (s *ApiServer) Engine() *gin.Engine {
	return s.engine
}

func (s *ApiServer) Name() string {
	if s.name != "" {
		return fmt.Sprintf("API_SERVER[%s]", s.name)
	}
	return "API_SERVER"
}

func (s *ApiServer) WithModule(t bool) {
	s.module = t
}

func (s *ApiServer) Module() bool {
	return s.module
}

func (s *ApiServer) Start() error {
	//作为模块不启动相关服务
	if s.module {
		return nil
	}

	server := s.Server()
	s.server = server

	logs.Out.Info("====== HttpServer[%s] %s", s.Name(), server.Addr)
	return server.ListenAndServe()
}

func (s *ApiServer) Server() *http.Server {
	return &http.Server{
		Addr:    s.serverConfig.ListenAddr(),
		Handler: s.engine,
	}
}

func (s *ApiServer) Stop() error {
	if s.server != nil {
		return s.server.Shutdown(context.Background())
	}
	return nil
}

func (s *ApiServer) WithName(name string) {
	s.name = name
}

// WithCors 设置跨域
func (s *ApiServer) WithCors(configs ...cors.Config) {
	//默认配置
	corsConfig := cors.DefaultConfig()
	corsConfig.AllowOrigins = []string{"*"}
	corsConfig.AllowCredentials = true
	corsConfig.AllowHeaders = append(corsConfig.AllowHeaders, consts.AcceptAuthorizationKey, consts.AcceptLanguageKey, "Access-Control-Allow-Origin", "Referer")
	corsConfig.OptionsResponseStatusCode = http.StatusOK

	if len(configs) > 0 {
		corsConfig = configs[0]
	}

	s.engine.Use(
		cors.New(corsConfig),
		gin_http.OptionRequestHandler(),
	)
}

// InitRouterForServer 注册路由
func (s *ApiServer) InitRouterForServer(a ...interfaces.ItfGinApiServer) {
	for i, v := range a {
		if utils.IsNil(v) {
			panic(fmt.Sprintf("GinApi-%d is nil", i))
		}
		if s.engine != nil {
			v.InitRouterForGin(s.engine)
		}
	}
}

func NewApiServer(engine *gin.Engine, conf configstc.ServerConfig) *ApiServer {
	return &ApiServer{
		engine:       engine,
		serverConfig: conf,
	}
}
